{
  // 在面向对象语言中，接口（Interfaces）是一个很重要的概念，它是对行为的抽象，而具体如何行动需要由类（classes）去实现（implements）。
  // TypeScript 中的接口是一个非常灵活的概念，除了可用于对类的一部分行为进行抽象以外，也常用于对「对象的形状（Shape）」进行描述。
  {
    // 对「对象的形状（Shape）」进行描述
    interface Person {
      // readonly id: number;
      name: string;
      age?: number;
      // 任意属性
      // 一旦定义了任意属性，那么确定属性和可选属性的类型都必须是它的类型的子集
      // 一个接口中只能定义一个任意属性。
      // [propName: string]: any;
    }

    /**
     * Type '{ name: string; age: number; gender: string; }' is
     * not assignable to type 'Person'.
     * Object literal may only specify known properties, and
     * 'gender' does not exist in type 'Person'.
     */
    let tom: Person = {
      name: "Tom",
      // age: 25, //可选属性：
      // gender: "male",
    };
    // 只读的约束存在于第一次给对象赋值的时候，而不是第一次给只读属性赋值的时候
    // tom.id = "23";
  }
  {
    // 类与接口
    // 行为的抽象，不能直接实例化，需要类（class）去实现（implements）
    // 门是一个类，防盗门是门的子类。如果防盗门有一个报警器的功能，我们可以简单的给防盗门添加一个报警方法。这时候如果有另一个类，车，也有报警器的功能，就可以考虑把报警器提取出来，作为一个接口，防盗门和车都去实现它

    {
      // 类实现接口
      interface Alarm {
        alert(): void;
      }

      interface Light {
        lightOn(): void;
        lightOff(): void;
      }

      // 类可以实现多个接口
      class Car implements Alarm, Light {
        alert() {
          console.log("Car alert");
        }
        lightOn() {
          console.log("Car light on");
        }
        lightOff() {
          console.log("Car light off");
        }
      }
    }

    {
      // 接口继承接口
      interface Alarm {
        alert(): void;
      }

      interface LightAlarm extends Alarm {
        lightOn(): void;
        lightOff(): void;
      }
    }
  }

  {
    // 接口继承类
    // 常见的面向对象编程语言都是不允许的，但是 TypeScript 可以
    // 当接口继承了一个类类型时，它会继承类的成员但不包括其实现。
    // 当你创建了一个接口继承了一个拥有私有或受保护的成员的类时，这个接口类型只能被这个类或其子类所实现（implements）。
    class Control {
      private state: any;
    }

    interface SelectableControl extends Control {
      select(): void;
    }

    // Control 的子类才能实现 SelectableControl
    class Button extends Control implements SelectableControl {
      select() {}
    }

    class TextBox extends Control {
      select() {}
    }

    // 不是 Control 的子类，state 属性也不是通过继承 Control 得来的，不能实现 SelectableControl
    // class ImageControl implements SelectableControl {
    //   // Error: Class 'ImageControl' incorrectly implements interface 'SelectableControl'.
    //   //  Types have separate declarations of a private property 'state'.
    //   private state: any;
    //   select() {}
    // }
  }
}
